//------------------------------------------------------------------------------
// X2TK Graphic Toolkit
// Copyright (C) 2006-2007 Janusz Kowalski
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//------------------------------------------------------------------------------

#include "x2tk_Window.h"
#include "global.h"
#include "pmsg.h"
#include "x2tk.h"


namespace x2tk {

const int DRAGBAR_NONE = 0;
const int DRAGBAR_MOVE = 1;
const int DRAGBAR_RESIZE_W = 2;
const int DRAGBAR_RESIZE_H = 4;
const int DRAGBAR_RESIZE_X = 8;
const int DRAGBAR_RESIZE_Y = 16;

class DragBar : public Widget {
  private:
    bool drag;
    int mx,my;
    int type_;
    Widget *victim_;
    const char *label_;
    Font font_;
    Image img_;
    Image imgShaded_;
  public:
    DragBar(int x, int y, int w, int h, Widget *victim, int type=DRAGBAR_NONE) : Widget(x,y,w,h) {
      drag=false;
      victim_=victim;
      type_=type;
      label_=0;
      font_=Font(X2D_PATH_FONT "HiTechFont_White.png");
      img_ = Image(X2D_PATH_DATA "circles/texA.png");
      imgShaded_ = Image(X2D_PATH_DATA "circles/texB.png");
    }
    
    virtual void draw(GraphicContext &g) {
      if(getParent()==0) return;
      

      // !! This should be changed.
      /*if(getParent()->hasFocus()) g.setColor(x2tk::getColor(FRAME_ACTIVE));
      else*/ g.setColor(x2tk::getColor(FRAME_NORMAL));
      g.filledRectangle(0,0,getW(),getH());
      if(label_!=0) font_.drawText(g,2,2,label_);
    }
    
    bool mouseDown(int type) {
      if(!!getParent()) getParent()->setFocusOwner(this);
      
      mx=getMouseX();
      my=getMouseY();
      if(mx>0 && mx<0+getW() && my>0 && my<0+getH()) {
        drag=true;
        return true;
      }
      return false;
    }
    
    void mouseUp(int type) {
      drag=false;
    }
    
    void setLabel(const char *label) {
      label_ = label;
    }
    
    void mouseMove(int x, int y) {
      if(drag && (victim_!=0)) {
        if(type_ & DRAGBAR_MOVE) {
          victim_->setX(victim_->getX()+x-mx);
          victim_->setY(victim_->getY()+y-my);
        }
        
        if(type_ & DRAGBAR_RESIZE_W)
          victim_->resize(victim_->getW()+x-mx,victim_->getH());
        
        if(type_ & DRAGBAR_RESIZE_Y) {
          victim_->resize(victim_->getW(),victim_->getH()-y+my);
          victim_->setY(victim_->getY()+y-my);
        }
      }
    }
};

const int TitleBarH = 32;

static const int WND_BORDER = 2;
static const int WND_SPACE = 2;

void Window::rearrange() {
  if(content_) {
    content_->setX(4);
    content_->setY(20+4);
    content_->resize(getW()-8,getH()-20-8);
  }
  if(resizeBar_) {
    resizeBar_->setX(getW()-resizeBar_->getW()-WND_BORDER);
  }
  if(moveBar_) {
    moveBar_->resize(getW()-2*WND_BORDER-2*WND_SPACE-closeBtn_->getW()-resizeBar_->getW(),moveBar_->getH());
  }
}

Window::Window(const char *title, int x, int y, int w, int h) : Container(x,y,w,h) {
  tex = Image(X2D_PATH_DATA "circles/texD.png");
  // !! X2D constants shouldn't be used in X2TK.
  font_ = Font(X2D_PATH_FONT "HiTechFont_White.png");
  title_=title;
  content_=0;
  
  closeBtn_ = new Button(WND_BORDER, WND_BORDER,32,20,"X");
  add(closeBtn_);
  
  moveBar_=new DragBar(closeBtn_->getX()+closeBtn_->getW()+WND_SPACE,WND_BORDER,32,20, this, DRAGBAR_MOVE);
  add(moveBar_);
  
  resizeBar_=new DragBar(0,WND_BORDER,32,20, this, DRAGBAR_RESIZE_W | DRAGBAR_RESIZE_Y);
  add(resizeBar_);
  
  // !! Not nice.
  static_cast<DragBar*>(moveBar_)->setLabel(title);
  
  closeBtn_->setAction(1);
  
  setKeepFocus(true);
}

// Obsolete.
void Window::resize(int w, int h) {
  Container::resize(w,h);
  rearrange();
}

void Window::action(int id, Widget *origin) {
  if(id==1) delete this;
}

void Window::setContent(Widget *content) {
  // !! What happens with the previous content??
  add(content);
  content_=content;
  rearrange();
}

void Window::draw(GraphicContext &g) {
  g.setColor(x2tk::getColor(AREA_NORMAL));
  g.filledRectangle(0,0,getW(),getH());

  if(hasFocus()) g.setColor(x2tk::getColor(FRAME_ACTIVE));
  else g.setColor(x2tk::getColor(FRAME_NORMAL));
  g.rectangle(0,0,getW(),getH());
  
  //if(tex.getSurf()==0) g.colorFill(0x80,0x80,0x80);
  //else g.textureFill(tex.getSurf(), 1, 1, getW()-2, getH()-2);
  Container::draw(g);
}

} // namespace x2tk
